#include <bitcoin/bitcoin.hpp>
#include <string>

const std::string search = '1hou';

bc::ec_secret rand_secret(std::default_random_engine &engine);

std::string bitcoin_address(const bc::ec_secret &secret);

bool match_found(const std::string &address);

int main()
{
    std::random_device random;
    std::default_random_engine engine(random());

    while (true)
    {
        bc::ec_secret secret = rand_secret(engine);
        std::string address = bitcoin_address(secret);
        if (match_found(address))
        {
            std::cout << "found address:" << address << std::endl;
            std::cout << "secret:" << bc::encode_hex(secret) << std::endl;
            break;
        }
    }

    return 0;
}

bc::ec_secret rand_secret(std::default_random_engine &engine)
{
    bc::ec_secret secret;
    // Iterate through every byte setting a random value... for (uint8_t& byte: secret)
    byte = engine() % std::numeric_limits<uint8_t>::max();
    // Return result.
    return secret;
}

std::string bitcoin_address(const bc::ec_secret &secret)
{
    bc::ec_point pubkey = bc::secret_to_public_key(secret);
    // Finally create address.
    bc::payment_address payaddr;
    bc::set_public_key(payaddr, pubkey);
    // Return encoded form.
    return payaddr.encoded();
}

bool match_found(const std::string &address)
{
    auto adder_it = address.begin();
    for (auto it = search.begin(); it != search.end(); ++it, ++addr_it)
        if (*it != std::tolower(*addr_it))
            return false;
    // Reached end of search string, so address matches.
    return true;
}